<template>
  <div class="system-menu">
    <div class="btn-box">
      <el-button
        v-permission="['menu:add']"
        type="success"
        icon="el-icon-plus"
        @click="dialogShow = true"
      >
        新增
      </el-button>
      <el-button type="primary" icon="el-icon-refresh" @click="getMenuList">刷新</el-button>
    </div>
    <el-table
      tree
      lazy
      style="width: 100%"
      row-key="id"
      :default-expand-all="defaultExpandAll"
      :data="list"
      :tree-props="{ children: 'children', hasChildren: 'true' }"
    >
      <el-table-column label="菜单标题" prop="title" min-width="70"></el-table-column>
      <el-table-column label="排序" prop="menuSort" width="80"></el-table-column>
      <el-table-column label="权限标识" prop="permission"></el-table-column>
      <el-table-column label="组件路径" prop="component"></el-table-column>
      <el-table-column label="路由名称" prop="name"></el-table-column>
      <el-table-column label="路由地址" prop="path"></el-table-column>
      <el-table-column label="可见" prop="hidden" width="80">
        <template slot-scope="scope">
          <div>
            {{ scope.row.hidden == 1 ? '否' : '是' }}
          </div>
        </template>
      </el-table-column>
      <el-table-column prop="createdAt" label="创建时间" width="150"></el-table-column>
      <el-table-column label="操作" width="180">
        <template slot-scope="scope">
          <div>
            <el-button
              type="primary"
              icon="el-icon-plus"
              @click="addInScope(scope.row)"
              v-if="scope.row.type !== 2"
              v-permission="['menu:add']"
            ></el-button>
            <el-button
              v-permission="['menu:check']"
              type="success"
              icon="el-icon-edit"
              @click="check(scope.row)"
            ></el-button>
            <el-button
              v-permission="['menu:del']"
              type="danger"
              icon="el-icon-delete"
              @click="del(scope.row)"
            ></el-button>
          </div>
        </template>
      </el-table-column>
    </el-table>

    <el-dialog
      :show-close="false"
      :title="dialogInfo.id ? `修改菜单` : `新增菜单`"
      :visible="dialogShow"
    >
      <el-form
        label-position="top"
        :rules="menuRule"
        :model="dialogInfo"
        ref="menuForm"
        @submit.native.prevent
      >
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item prop="type" label="菜单类型">
              <el-radio-group v-model="dialogInfo.type">
                <el-radio-button :label="0">目录</el-radio-button>
                <el-radio-button :label="1">菜单</el-radio-button>
                <el-radio-button :label="2">按钮</el-radio-button>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item prop="hidden" label="菜单可见" v-if="!isTypeBtn">
              <el-radio-group v-model="dialogInfo.hidden">
                <el-radio-button :label="0">是</el-radio-button>
                <el-radio-button :label="1">否</el-radio-button>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item prop="menuSort" label="菜单排序">
              <el-input-number
                :min="1"
                :max="999"
                v-model.trim="dialogInfo.menuSort"
              ></el-input-number>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item prop="title" label="菜单标题">
              <el-input v-model.trim="dialogInfo.title"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="!isTypeBtn">
            <el-form-item prop="path" label="路由地址(配置在route下的地址,需要/)">
              <el-input v-model.trim="dialogInfo.path"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20" v-if="isTypePage">
          <el-col :span="12">
            <el-form-item prop="name" label="路由名称(用于生成路由中的name)">
              <el-input v-model.trim="dialogInfo.name"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item prop="component" label="组件路径(在代码中的路径)">
              <el-input v-model.trim="dialogInfo.component"></el-input>
            </el-form-item>
          </el-col>
        </el-row>

        <el-form-item prop="permission" label="权限标识(唯一,不重复)" v-if="!isTypeMenu">
          <el-input v-model.trim="dialogInfo.permission"></el-input>
        </el-form-item>

        <el-form-item prop="pid" label="上级目录">
          <treeselect
            v-model="dialogInfo.pid"
            :options="treeSelectList"
            :normalizer="treeSelectNormalizer"
          />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button icon="el-icon-close" @click="closeDialog">关 闭</el-button>
        <el-button type="success" @click="saveMenu" icon="el-icon-check">保 存</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
  import { FormRuleConf } from '@/config';
  import { cloneDeep } from 'lodash';

  import Treeselect from '@riophae/vue-treeselect';
  import '@riophae/vue-treeselect/dist/vue-treeselect.css';

  const DATA_TMP = {
    hidden: 0,
    type: 0,
    menuSort: 999,
    pid: 0,
  };

  export default {
    data() {
      return {
        list: [],
        treeSelectList: [],

        loading: false,
        dialogShow: false,
        defaultExpandAll: false,
        dialogInfo: cloneDeep(DATA_TMP),
        ...FormRuleConf.Menu,
        pagination: {
          size: 1000,
        },
      };
    },
    components: { Treeselect },
    computed: {
      isTypeMenu() {
        return this.dialogInfo.type === 0;
      },
      isTypePage() {
        return this.dialogInfo.type === 1;
      },
      isTypeBtn() {
        return this.dialogInfo.type === 2;
      },
    },
    mounted() {
      this.getMenuList();

      this.updateCategoryList();
    },
    methods: {
      /**
       * 更新目录列表
       */
      updateCategoryList() {
        this.$service.SysMenuCatalogueList().then((res) => [(this.treeSelectList = res)]);
      },
      /**
       * 获取菜单数据
       */
      getMenuList() {
        this.$service
          .SysMenuList({
            size: 10000,
          })
          .then((res) => {
            this.list = res;
          });
      },
      /**
       * 保存菜单
       */
      saveMenu() {
        this.$refs['menuForm'].validate((valid) => {
          if (valid && !this.loading) {
            this.loading = true;
            const {
              type,
              title,
              hidden,
              menuSort,
              path,
              component,
              name,
              permission,
              pid,
              id,
            } = this.dialogInfo;

            let payload = {
              id,
              type,
              menuSort,
              title,
              pid,
            };

            switch (type) {
              case 0:
                payload = {
                  hidden,
                  path,
                  ...payload,
                };
                break;
              case 1:
                payload = {
                  hidden,
                  path,
                  permission,
                  component,
                  name,
                  ...payload,
                };
                break;
              case 2:
                payload = {
                  permission,
                  ...payload,
                };
                break;
            }

            this.$service
              .SysMenuSave(payload, {
                ...JSON_HEADER,
              })
              .then((res) => {
                this.$message.success('保存菜单成功');
                this.closeDialog();
                this.getMenuList();
                this.updateCategoryList();
              })
              .finally(() => {
                this.loading = false;
              });
          }
        });
      },
      /**
       * TreeSelect Customize Key Names
       */
      treeSelectNormalizer(node) {
        return {
          id: node.id,
          label: node.title,
          children: node.children,
        };
      },

      addInScope(row) {
        this.dialogShow = true;
        this.dialogInfo = {
          ...cloneDeep(DATA_TMP),
          pid: row.id,
        };
      },
      /**
       * 修改现有的数据
       */
      check(row) {
        this.dialogShow = true;
        this.dialogInfo = cloneDeep(row);
      },
      /**
       * 删除数据
       */
      del(row) {
        this.$confirm(`确认删除 ${row.title} 这个菜单吗?`, '真的吗?').then((res) => {
          this.$service
            .SysMenuDel({
              id: row.id,
            })
            .then(() => {
              this.$message.success('删除完成');
              this.getMenuList();
            });
        });
      },
      /**
       * 关闭弹窗
       */
      closeDialog() {
        this.dialogShow = false;
        this.dialogInfo = cloneDeep(DATA_TMP);
      },
    },
  };
</script>

<style lang="less" scoped>
  .system-menu {
  }
</style>
